package com.shopx.oss.service.impl;

import com.shopx.base.exception.OriginException;
import com.shopx.base.service.base.BaseService;
import com.shopx.core.common.CommonConstant;
import com.shopx.core.utils.DateTimeUtil;
import com.shopx.core.utils.FileUtil;
import com.shopx.core.utils.StringUtil;
import com.shopx.oss.service.IFileService;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Random;

/**
 * TODO
 *
 * @author:lituo
 * @date:2021/12/12
 **/
@Service
@Slf4j
public class FileServiceImpl extends BaseService implements IFileService {

  @Value("${file.imgSuffix}")
  private String imgSuffix;

  @Value("${file.workSuffix}")
  private String workSuffix;

  @Value("${file.cadSuffix}")
  private String cadSuffix;

  @Value("${file.maxNum.img}")
  private String imgMaxNum;

  @Value("${file.maxNum.work}")
  private String workMaxNum;

  @Value("${file.maxNum.cad}")
  private String cadMaxNum;


  @Value("${file.maxSize.img}")
  private String imgMaxSize;

  @Value("${file.maxSize.work}")
  private String workMaxSize;

  @Value("${file.maxSize.cad}")
  private String cadMaxSize;


  @Value("${file.oss.localPath}")
  private String localPath;

  @Value("${file.oss.filePrefix}")
  private String filePrefix;

  @Value("${file.oss.fileName}")
  private String fileName;

  @Value("${file.compress.scale}")
  private String scale;

  @Value("${file.compress.quality}")
  private String quality;

  @Value("${file.compress.limitSize}")
  private String limitSize;


  @Override
  public String uploadFile(List<MultipartFile> list, String fileType,String cpId) throws Exception {
    String filePath = "";
    //验证文件格式
    checkFileSuffix(list, fileType);
    //验证一次文件上传数量
    checkFileNumber(list, fileType);
    //验证上传文件大小
    checkFileSize(list, fileType);
    //上传
    filePath = this.upload(list, fileType,cpId);
    return filePath.substring(0, filePath.length() - 1);
  }

  /**
   * 上传 TODO 压缩图片
   *
   * @param list
   * @return java.lang.String
   * @author lituo
   * @date 6:07 PM 2021/12/12
   */
  private String upload(List<MultipartFile> list, String fileType,String cpId) throws Exception {
    log.info("upload.begin");
    String curDt = DateTimeUtil.getDate8();
    String filePath = localPath + File.separator + cpId+ File.separator + curDt;
    if(CommonConstant.FileType.COREIMG.equals(fileType)){
      //视频文件要迁移，新建目录存储
      filePath = localPath + File.separator + cpId+File.separator + "projFile"+File.separator + curDt;
    }else if(CommonConstant.FileType.CAD.equals(fileType)){
      //视频文件要迁移，新建目录存储
      filePath = localPath + File.separator + cpId+File.separator + "projCad"+File.separator + curDt;
    }
    FileUtil.createFile(filePath);
    String fileNames = "";
    for (MultipartFile file : list) {
      String ext = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
      String newNme = "";
      String origFileName = "";
      BufferedOutputStream stream = null;
      FileOutputStream fos = null;
      if (!file.isEmpty()) {
        try {
          byte[] bytes = file.getBytes();
          Random random = new Random();
          origFileName = String.valueOf(Math.abs(random.nextLong()));
          newNme = origFileName + "." + ext;
          String upliadFilePath = filePath + File.separator + newNme;
          fos = new FileOutputStream(new File(upliadFilePath));
          stream = new BufferedOutputStream(fos);
          stream.write(bytes);
          if (CommonConstant.FileType.COREIMG.equals(fileType)) {
            //核心文件
            double fileSize = (double) file.getSize() / 1048576;
            log.info("fileSize:{}",fileSize);
            if (fileSize > Double.valueOf(0.2)) {
              //大于1MB的图片，压缩50%
              log.info("COREIMG-90");
              Thumbnails.of(upliadFilePath).scale(Float.valueOf("0.9")).outputQuality(Float.valueOf("1")).toFile(upliadFilePath);
            } if (fileSize > Double.valueOf(1)) {
              log.info("COREIMG-50");
              //大于1MB的图片，压缩50%
              Thumbnails.of(upliadFilePath).scale(Float.valueOf("0.8")).outputQuality(Float.valueOf("0.8")).toFile(upliadFilePath);
            }else if(fileSize > Double.valueOf(2)){
              log.info("COREIMG-30");
              //大于2M，压缩到30%
              Thumbnails.of(upliadFilePath).scale(Float.valueOf("0.5")).outputQuality(Float.valueOf("0.6")).toFile(upliadFilePath);
            }else if(fileSize > Double.valueOf(3)){
              //大于3M，压缩到20%
              log.info("COREIMG-20");
              Thumbnails.of(upliadFilePath).scale(Float.valueOf("0.4")).outputQuality(Float.valueOf("0.5")).toFile(upliadFilePath);
            }else if(fileSize > Double.valueOf(4)){
              //大于4M，压缩到10%
              log.info("COREIMG-10");
              Thumbnails.of(upliadFilePath).scale(Float.valueOf("0.3")).outputQuality(Float.valueOf("0.5")).toFile(upliadFilePath);
            }
          }else if(CommonConstant.FileType.IMG.equals(fileType)) {
            //非核心文件
            double fileSize = (double) file.getSize() / 1048576;
            if (fileSize > Double.valueOf(0)) {
              //大于1MB的图片，压缩50%
              log.info("IMG-30");
              Thumbnails.of(upliadFilePath).scale(Float.valueOf("0.5")).outputQuality(Float.valueOf("0.5")).toFile(upliadFilePath);
            }else if (fileSize > Double.valueOf(1)) {
              //大于1MB的图片，压缩50%
              log.info("IMG-20");
              Thumbnails.of(upliadFilePath).scale(Float.valueOf("0.4")).outputQuality(Float.valueOf("0.4")).toFile(upliadFilePath);
            }else if(fileSize > Double.valueOf(2)){
              //大于4M，压缩到10%
              log.info("IMG-10");
              Thumbnails.of(upliadFilePath).scale(Float.valueOf("0.2")).outputQuality(Float.valueOf("0.2")).toFile(upliadFilePath);
            }
          }
        } catch (Exception e) {
          log.info("上传失败", e);
          throw new OriginException("99999", "上传失败");
        } finally {
          if (stream != null) {
            stream.flush();
            stream.close();
          }
          if(fos!=null){
            fos.close();
          }
        }
      } else {
        log.error("上传文件为空");
        throw new OriginException("99999", "上传失败");
      }
      if(CommonConstant.FileType.COREIMG.equals(fileType)){
        //视频文件要迁移，新建目录存储
        fileNames += fileName + File.separator + cpId+   File.separator + "projFile"+File.separator + curDt + File.separator + newNme + ":" + origFileName + ",";
      }else if(CommonConstant.FileType.CAD.equals(fileType)){
        fileNames = fileName + File.separator + cpId+   File.separator + "projCad"+File.separator + curDt + File.separator + newNme + ":" + origFileName + ",";
      }else{
        fileNames += fileName + File.separator + cpId + File.separator + curDt + File.separator + newNme + ":" + origFileName + ",";
      }


    }
    log.info("finish.upload:{}", fileNames);
    return fileNames;
  }

  /**
   * 验证一次文件上传数量
   *
   * @param file
   * @param fileType
   * @return void
   * @author lituo
   * @date 5:46 PM 2021/12/12
   */
  private void checkFileNumber(List<MultipartFile> file, String fileType) {
    int fileSize = file.size();
    if (CommonConstant.FileType.IMG.equals(fileType)) {
      if (fileSize > Integer.valueOf(imgMaxNum)) {
        throw new OriginException("88888", "一次最多上传" + imgMaxNum + "张图片");
      }
    }else  if (CommonConstant.FileType.COREIMG.equals(fileType)) {
      if (fileSize > Integer.valueOf(imgMaxNum)) {
        throw new OriginException("88888", "一次最多上传" + imgMaxNum + "张图片");
      }
    } else if (CommonConstant.FileType.FILE.equals(fileType)) {
      if (fileSize > Integer.valueOf(workMaxNum)) {
        throw new OriginException("88888", "一次最多上传" + workMaxNum + "个文件");
      }
    } else if (CommonConstant.FileType.CAD.equals(fileType)) {
      if (fileSize > Integer.valueOf(cadMaxNum)) {
        throw new OriginException("88888", "一次最多上传" + cadMaxNum + "张CAD文件");
      }
    } else {
      throw new OriginException("88888", "上传文件格式有误");
    }
  }

  /**
   * 验证上传文件大小
   *
   * @param file
   * @param fileType
   * @return void
   * @author lituo
   * @date 5:46 PM 2021/12/12
   */
  private void checkFileSize(List<MultipartFile> file, String fileType) {
    String fileSize = "";
    if (CommonConstant.FileType.IMG.equals(fileType)) {
      fileSize = imgMaxSize;
    }else if (CommonConstant.FileType.COREIMG.equals(fileType)) {
      fileSize = imgMaxSize;
    } else if (CommonConstant.FileType.FILE.equals(fileType)) {
      fileSize = workMaxSize;
    } else if (CommonConstant.FileType.CAD.equals(fileType)) {
      fileSize = cadMaxSize;
    } else {
      throw new OriginException("88888", "上传文件格式有误");
    }
    for (MultipartFile f : file) {
      if (!FileUtil.checkFileSize(f.getSize(), Integer.parseInt(fileSize), "M")) {
        throw new OriginException("88888", "上传文件不能超过" + fileSize + "MB");
      }
    }
  }

  /**
   * 验证文件是否有效
   *
   * @param file（1：图片；2：文件；3：cad文件）
   * @param fileType
   * @return void
   * @author lituo
   * @date 5:38 PM 2021/12/12
   */
  private void checkFileSuffix(List<MultipartFile> file, String fileType) {
    String fileSuffix = "";
    if (CommonConstant.FileType.IMG.equals(fileType)) {
      fileSuffix = imgSuffix;
    } else if (CommonConstant.FileType.COREIMG.equals(fileType)) {
      fileSuffix = imgSuffix;
    } else if (CommonConstant.FileType.FILE.equals(fileType)) {
      fileSuffix = workSuffix;
    } else if (CommonConstant.FileType.CAD.equals(fileType)) {
      fileSuffix = cadSuffix;
    } else {
      throw new OriginException("88888", "上传文件格式有误");
    }

    boolean fileMatch = false;
    for (MultipartFile f : file) {
      String fileName = f.getOriginalFilename();
      for (String suffix : fileSuffix.split(",")) {
        if (StringUtil.isEmpty(suffix)) {
          continue;
        }
        if (fileName.toLowerCase().indexOf(suffix) >= 0) {
          fileMatch = true;
          break;
        }
      }
      if (!fileMatch) {
        throw new OriginException("88888", "上传文件格式错误");
      }
    }
  }

}
